

import {Local} from "./local"
import {has,set,get} from "lodash-es"

// interface Config {
//     timeout?:number
//     heart?:{url:string,times:number}
//     handle?:(data:any) => void
// }

const GLOBAL_KEY = "MODELS_USER"

export const getInstance = () => {
    if(has(window,GLOBAL_KEY)){
        // @ts-ignore
        return get(window,GLOBAL_KEY) as USER
    }
    return undefined;
}

export interface Config {
    key?:string
    refreshKey?:string
    timeout?:number
    userProps?:{id:string,name:string,role:string,nick:string,avator:string}
    refresh?:() => Promise<void>
    refreshToken?:() => Promise<string>
    getUserInfo?:() => Promise<any>
    getMenus?:() => Promise<any[]>
    getButtons?:() => Promise<any[]>
    getRoutes?:() => Promise<any[]>
}

/**
 * 鉴权模块
 * 
 * 功能列表
 * 1. 存储权限信息
 * 2. 配置失效规则 超时 心跳
 * 3. 启用刷新功能
 * 4. 失效时触发钩子函数
 */
export class USER {
    //
    constructor(config:Config = {}){
        if(has(window,GLOBAL_KEY)){
            // @ts-ignore
            return get(window,GLOBAL_KEY) as USER;
        }
        Object.keys(config).forEach(k => {
            if(has(this,k)){
                set(this,k,get(config,k))
            }
        })
        set(window,GLOBAL_KEY,this)
    }
    
    // token
    tokenKey = "AUTH_TOKEN_CACHE_KEY"
    refreshKey="AUTH_REFRESH_TOKEN_CACHE_KEY"
    timeout=2000000;
    refreshToken = async () => '';
    getUserInfo = async () => ({})
    getMenus = async () => []
    getButtons = async () => []
    getRoutes = async () => []

    // user
    userProps = {id:'id',role:"role",name:"name",nick:"nick",avator:"avator"};
    id = '';
    role = '';
    name = '';
    nick = ''
    avator = '';
    info = {}
    // auth
    menus = []
    buttons = []
    routes = []
    //
    hasRefresh = false;
    autoRefresh = false;
    //
    refreshAuthToken= async () => {
        if(this.autoRefresh){
            const val = await this.refreshToken();
            val && this.setToken(val)
        }
        return this;
    }

    refreshUserInfo = async (props = this.userProps) => {
        const data = await this.getUserInfo();
        Object.keys(props).forEach(k => {
            const sk = get(props,k);
            if(has(data,sk)){
                set(this,k,get(data,sk))
            }
        })
        return this;
    }

    refreshMenus = async () => {
        const menus = await this.getMenus();
        this.menus = menus;
    }

    refreshButtons = async () => {
        const menus = await this.getButtons();
        this.menus = menus;
    }

    refreshRoutes = async () => {
        const menus = await this.getRoutes();
        this.menus = menus;
    }

    setToken(val:string,key = this.tokenKey){
        Local.set(key,val,this.timeout,this.refreshAuthToken)
        return this;
    }
    getToken(key = this.tokenKey){
        return Local.get(key);
    }
    hasToken(key=this.tokenKey){
        return Local.has(key);
    }

    getRefreshToken(key=this.refreshKey){
        return Local.get(key)
    }
    setRefreshToken(val:string,key = this.refreshKey){
        this.hasRefresh = true;
        Local.set(key,val)
        return this;
    }

    // USER 

    // role

}